package io.xiaojl.xj2ee.task.config;

import java.io.PrintWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import io.xiaojl.xj2ee.task.utils.JsonKit;
import io.xiaojl.xj2ee.task.utils.R;
import io.xiaojl.xj2ee.task.utils.XjeeException;

/**  
 * <p>Title: GlobalExceptionHandler</p>  
 *
 * <p>Description: 异常统一处理</p>  
 *
 * @author jilong.xiao  
 * @date 2018年5月28日  
 */
@ControllerAdvice
public class GlobalExceptionHandler {
	private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
	
	public static final String DEFAULT_ERROR_VIEW = "error";

    @ExceptionHandler(value = XjeeException.class)
    @ResponseBody
    public Object jsonErrorHandler(HttpServletRequest req, XjeeException e) throws Exception {
    	log.error("系统出现[XjeeException]异常：",e);
    	R error = R.error(e.getMessage());
        return error;
    }
    
    /**
    *
    * 捕获@RequestMapping注解的方法抛出的Exception异常并处理：
    * 若是ajax请求或请求端接受json数据则返回json信息；否则转发（forward）到默认的/error映射，error.html页面展示信息,因为是forward所以不用再经过拦截器处理。
    * 若是去掉该方法或者去掉注解@ExceptionHandler，则spring-boot对异常的处理：302重定向到到默认的错误异常处理映射/error,因为是302重定向，
    * 所以会经过拦截器处理。
    * @param req
    * @param e
    * @return
    * @throws Exception
    */
   @ExceptionHandler(value = Exception.class)
   public ModelAndView defaultErrorHandler(HttpServletRequest req, HttpServletResponse res, Exception e) throws Exception {
	   log.error("系统出现[Exception]异常：",e);
       String accept = req.getHeader("Accept");
       String requestType = req.getHeader("X-Requested-With");
       boolean ajax = (requestType != null && requestType.equalsIgnoreCase("XMLHttpRequest")) ? true : false;
       if(ajax || accept.contains("json")) {     //ajax请求或者请求端接受json数据
    	   res.setCharacterEncoding("UTF-8");
    	   res.setContentType("text/html;charset=UTF-8");
           PrintWriter writer = res.getWriter();
           writer.write(JsonKit.toJson(R.error("系统繁忙,请稍后再试!")));
           writer.flush();
           writer.close();
           return null;
       } else {
           ModelAndView mav = new ModelAndView();
           mav.addObject("exception", e);
           mav.addObject("url", req.getRequestURL());
           mav.setViewName(DEFAULT_ERROR_VIEW);
           return mav;
       }
   }
}
